/*
 * Copyright 2017-2021 Pranav Pandey
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.pranavpandey.ohos.dynamic.toasts.watcher;

import com.pranavpandey.ohos.dynamic.toasts.ImageTint;

import ohos.agp.colors.RgbColor;
import ohos.agp.components.Component;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.BlendMode;
import ohos.agp.render.ColorFilter;
import ohos.agp.utils.Color;
import ohos.app.Context;

import java.util.Optional;

/**
 * Helper class to perform {@link Element} operations.
 */
public class DynamicDrawableUtils {
    /**
     * Set background of a given component in an efficient way by detecting the ohos SDK
     * at runtime.
     *
     * @param component The component to set the background.
     * @param element The background Element to be set.
     */
    public static void setBackground(Component component, Element element) {
        component.setBackground(element);
    }

    /**
     * Apply color filter and return the mutated Element so that, all other references
     * do not change.
     *
     * @param element The Element to be colorized.
     * @param wrap {@code true} to {@code wrap} the Element so that it may be used for
     * tinting across the different API levels.
     * @param colorFilter The color filter to be applied on the Element.
     * @return The Element after applying the color filter.
     * @see Element#(ColorFilter)
     * @see ColorFilter
     */
    public static Element colorizeElement(Element element, boolean wrap, ColorFilter colorFilter) {
        return element;
    }

    /**
     * Colorize and return the mutated Element so that, all other references do not change.
     *
     * @param element The Element to be colorized.
     * @param color The color to colorize the Element.
     * @param wrap {@code true} to {@code wrap} the Element so that it may be used for
     * tinting across the different API levels.
     * @param mode The porter duff mode to be used.
     * @return The Element after applying the color filter.
     * @see Element#(int, BlendMode)
     * @see BlendMode
     */
    public static Element colorizeElement(Element element,
        boolean wrap, int color, BlendMode mode) {
        BlendMode curMode = mode;
        if (element != null) {
            if (curMode == null) {
                curMode = BlendMode.SRC_IN;
            }
            ImageTint.getTintElement(element, RgbColor.fromArgbInt(color).asArgbInt(), curMode);
        }
        return element;
    }

    /**
     * Colorize and return the mutated Element so that, all other references do not change.
     *
     * @param element The Element to be colorized.
     * @param color The color to colorize the Element.
     * @param mode The porter duff mode to be used.
     * @return The Element after applying the color filter.
     * @see Element
     */
    public static Element colorizeElement(Element element, int color, BlendMode mode) {
        return colorizeElement(element, true, color, mode);
    }

    /**
     * Colorize and return the mutated Element so that, all other references do not change.
     *
     * @param element The Element to be colorized.
     * @param wrap {@code true} to {@code wrap} the Element so that it may be used for
     * tinting across the different API levels.
     * @param color The color to colorize the Element.
     * @return The Element after applying the color filter.
     * @see Element 组件
     */
    public static Element colorizeElement(Element element, boolean wrap, int color) {
        return colorizeElement(element, wrap, color, BlendMode.SRC_IN);
    }

    /**
     * Colorize and return the mutated element so that, all other references do not change.
     *
     * @param element The element to be colorized.
     * @param color The color to colorize the element.
     * @return The element after applying the color filter.
     */
    public static Element colorizeElement(Element element, int color) {
        return colorizeElement(element, true, color);
    }

    /**
     * Apply color filter and return the mutated element so that, all other references
     * do not change.
     *
     * @param element The element to be colorized.
     * @param colorFilter The color filter to be applied on the element.
     * @return The element after applying the color filter.
     * @see Element#
     * @see ColorFilter
     */
    public static Element colorizeElement(Element element, ColorFilter colorFilter) {
        return colorizeElement(element, true, colorFilter);
    }

    /**
     * Get a gradient Element according to the supplied Element.
     *
     * @param context 上下文
     * @param width The width in dip for the Element.
     * @param height The height in dip for the Element.
     * @param element The Element Element to create the gradient Element.
     * @param color The color for the Element.
     * @return The gradient Element according to the supplied parameters.
     */
    public static Element getCornerElement(Context context, float width,
        float height, ShapeElement element, int color) {
        element.setRgbColor(RgbColor.fromArgbInt(color));
        return element;
    }

    /**
     * Get a gradient Element according to the supplied Element.
     *
     * @param context 上下文
     * @param width The width in dip for the Element.
     * @param height The height in dip for the Element.
     * @param element The Element Element to create the gradient Element.
     * @return The gradient Element according to the supplied parameters.
     */
    public static Element getCornerElement(Context context, float width,
        float height, ShapeElement element) {
        return getCornerElement(context, width, height, element, Color.WHITE.getValue());
    }

    /**
     * Get a gradient Element according to the supplied Element.
     *
     * @param context 上下文
     * @param element The Element Element to create the gradient Element.
     * @param color The color for the Element.
     * @return The gradient Element according to the supplied parameters.
     */
    public static Element getCornerElement(Context context, ShapeElement element, int color) {
        return getCornerElement(context, 0, 0, element, color);
    }

    /**
     * Get a gradient Element according to the supplied Element.
     *
     * @param context 上下文
     * @param element The Element Element to create the gradient Element.
     * @return The gradient Element according to the supplied parameters.
     */
    public static Element getCornerElement(Context context, ShapeElement element) {
        return getCornerElement(context, 0, 0, element, Color.WHITE.getValue());
    }

    /**
     * Get a gradient Element according to the corner radius
     *
     * @param context 上下文
     * @param width The width in dip for the Element.
     * @param height The height in dip for the Element.
     * @param cornerRadius The corner size in dip for the Element.
     * @param color The color for the Element.
     * @return The gradient Element according to the supplied parameters.
     */
    public static Element getCornerElement(Context context, float width, float height,
        float cornerRadius, int color) {
        ShapeElement element = new ShapeElement();
        element.setCornerRadius(DynamicUnitUtils.convertDpToPixels(context, cornerRadius));
        return getCornerElement(context, width, height, element, color);
    }

    /**
     * Get a gradient Element according to the corner radius.
     *
     * @param context 上下文
     * @param width The width in dip for the Element.
     * @param height The height in dip for the Element.
     * @param cornerRadius The corner size in dip for the Element.
     * @return The gradient Element according to the supplied parameters.
     */
    public static Element getCornerElement(Context context, int width, int height, float cornerRadius) {
        return getCornerElement(context, width, height, cornerRadius, Color.WHITE.getValue());
    }

    /**
     * Get a gradient Element according to the corner radius.
     *
     * @param context 上下文
     * @param cornerRadius The corner size in dip for the Element.
     * @param color The color for the Element.
     * @return The gradient Element according to the supplied parameters.
     */
    public static Element getCornerElement(Context context, float cornerRadius, int color) {
        return getCornerElement(context, 0, 0, cornerRadius, color);
    }

    /**
     * Get a gradient Element according to the corner radius.
     *
     * @param context 上下文
     * @param cornerRadius The corner size in dip for the Element.
     * @return The gradient Element according to the supplied parameters.
     */
    public static Element getCornerElement(Context context, float cornerRadius) {
        return getCornerElement(context, 0, 0, cornerRadius, Color.WHITE.getValue());
    }
}
